Free Information Xchange '98 presents: Shipwreckers! - CD crack by Static Vengeance Requirements: hex editor and full install Time for another tutorial on CD check removal. This time we will be looking at a game called Shipwreckers! by Psygnosis. This game requires a 3D accelerator card and is kind of hard to describe. It's and action puzzle type game somewhat like a platform jumper but no platforms. Instead of a guy to run around you drive a ship and blow things up and solve sequence puzzles and such. Anywyas, the graphics rock on a 3Dfx card, and the game is fun to play. However as you can see by this article, there is a bug or two in Shipwreckers! Bugs that need to be FiX'ed. There's that same old pesky CD check that must pass before you can play a game. And as you know the whole point of doing a full install is so you can run the game off your hard drive. I just hate digging through a stack of CD's just so I can put the game CD in for a second for the copy protection to pass. I can live without the music tracks that come with the game. So load up W32Dasm and start disassembling sw.exe. When W32Dasm has finished it's work go up to the menu bar and select "Refs" and then select "String data references" from the drop down menu. From the refs box, grab the slider bar and scroll down to the string "SHIPWRECKERS! CD NOT PRESENT" and double click on it. This puts you in the middle of the routine that checks for the CD, and that routine goes something like this: * Referenced by a CALL at Address: |:004405C5 <-- Where this routine was called from | :00406FCC 53 push ebx :00406FCD 51 push ecx :00406FCE 52 push edx :00406FCF 55 push ebp :00406FD0 89E5 mov ebp, esp :00406FD2 89C3 mov ebx, eax * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040700C(U) | :00406FD4 E86BFDFFFF call 00406D44 <-- Check through WINMM.mciSendCommandA :00406FD9 833DA0644B0001 cmp dword ptr [004B64A0], 00000001 :00406FE0 752C jne 0040700E <-- Take this jump if CD is there :00406FE2 85DB test ebx, ebx :00406FE4 7424 je 0040700A :00406FE6 6A35 push 00000035 * Possible StringData Ref from Data Obj ->"Shipwreckers! CD Validator" | :00406FE8 6834204B00 push 004B2034 * Possible StringData Ref from Data Obj ->"SHIPWRECKERS! CD NOT PRESENT" <-- String that got us here | :00406FED 6850204B00 push 004B2050 :00406FF2 53 push ebx * Reference To: USER32.MessageBoxA, Ord:0010h | :00406FF3 2EFF1588134B00 Call dword ptr cs:[004B1388] :00406FFA 85C0 test eax, eax :00406FFC 7405 je 00407003 :00406FFE 83F802 cmp eax, 00000002 <-- You hit Cancel from dialog box :00407001 7507 jne 0040700A <-- If not Cancel then jump to retry * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00406FFC(C) | :00407003 31C0 xor eax, eax <-- Set for failed CD check :00407005 5D pop ebp :00407006 5A pop edx :00407007 59 pop ecx :00407008 5B pop ebx :00407009 C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00406FE4(C), :00407001(C) | :0040700A 89D8 mov eax, ebx :0040700C EBC6 jmp 00406FD4 <-- Go back and try again * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00406FE0(C) | :0040700E B801000000 mov eax, 00000001 <-- Everything is fine CD is present :00407013 5D pop ebp :00407014 5A pop edx :00407015 59 pop ecx :00407016 5B pop ebx :00407017 C3 ret Fairly simple when you look at it. The CD check is done through WINMM.DLL (WINdows Multi-Media) calls like WINMM.mciSendCommandA and WINMM.mciGetErrorStringA. The routine at 406D44 checks for a music track and compares against known values. If the routine doesn't find what it's looking for, then it's assumed you don't have the original CD in your CD-ROM drive. Okay, now let's take a quick look at the section of code that calls the CD check routine. That call and surounding code looks like this: :004405B6 A174274E00 mov eax, dword ptr [004E2774] :004405BB E8D05FFCFF call 00406590 :004405C0 A174274E00 mov eax, dword ptr [004E2774] :004405C5 E8026AFCFF call 00406FCC <-- Do the CD check :004405CA 85C0 test eax, eax <-- Check the return value for pass/fail :004405CC 752E jne 004405FC <-- Take this jump if it passed :004405CE 8B0D74274E00 mov ecx, dword ptr [004E2774] :004405D4 85C9 test ecx, ecx :004405D6 0F84E4FEFFFF je 004404C0 :004405DC 6A10 push 00000010 * Possible StringData Ref from Data Obj ->"Shipwreckers!" | :004405DE 6825414B00 push 004B4125 * Possible StringData Ref from Data Obj ->"Shipwreckers! requires the original " <-- Otherwise ask for the CD ->"CD to run." | :004405E3 6833414B00 push 004B4133 :004405E8 51 push ecx * Reference To: USER32.MessageBoxA, Ord:0010h | :004405E9 2EFF1588134B00 Call dword ptr cs:[004B1388] :004405F0 E83B000000 call 00440630 :004405F5 31C0 xor eax, eax <-- Setup for quiting back to Win95 :004405F7 5F pop edi :004405F8 5E pop esi :004405F9 59 pop ecx :004405FA 5B pop ebx :004405FB C3 ret * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004405CC(C) | :004405FC E80B020000 call 0044080C <-- If you got this far the CD is there :00440601 85C0 test eax, eax :00440603 0F84B7FEFFFF je 004404C0 :00440609 E8DA020000 call 004408E8 :0044060E 85C0 test eax, eax :00440610 0F84AAFEFFFF je 004404C0 :00440616 E805040000 call 00440A20 :0044061B 85C0 test eax, eax :0044061D 0F849DFEFFFF je 004404C0 :00440623 BE01000000 mov esi, 00000001 :00440628 89F0 mov eax, esi <-- Set eax "for continue with the game" :0044062A 5F pop edi :0044062B 5E pop esi :0044062C 59 pop ecx :0044062D 5B pop ebx :0044062E C3 ret There you have it, the easy way to crack this one is to change the call to the CD check routine to mov eax, 00000001, this forces the jne 004405FC at 4405CC to always be taken. This in turns makes the game playable without the CD present, which is the whole purpose of this article. There is one last little problem I wanted to correct: While the intro to the game is cool, I could do without it and the same goes for the Psygnosis logo and Dolby intros. So I set out to kill the call to those. Idealy I would have liked to have been able to disable just the Psygnosis and Dolby intros and keep the game intro. However if you have seen the game intro a couple of times you just want to skip it anyways. So here is how to get Shipwreckers! to start right up skipping all the logo intros and go straight into the main menu screen. First locate the refs to the intros: * Referenced by a CALL at Address: |:0043DC93 <-- Where the routine is called from | :0043E35C 53 push ebx :0043E35D 51 push ecx :0043E35E 52 push edx :0043E35F 55 push ebp :0043E360 89E5 mov ebp, esp :0043E362 81EC18010000 sub esp, 00000118 :0043E368 81ED96010000 sub ebp, 00000196 :0043E36E 68402E4E00 push 004E2E40 * Possible StringData Ref from Data Obj ->"%spsyglogo.mpx" <-- Psygnosis logo (mpeg file?) | :0043E373 6884404B00 push 004B4084 :0043E378 8D457E lea eax, dword ptr [ebp+7E] :0043E37B 50 push eax :0043E37C E8EF0B0100 call 0044EF70 :0043E381 83C40C add esp, 0000000C :0043E384 BBE0010000 mov ebx, 000001E0 :0043E389 BA80020000 mov edx, 00000280 :0043E38E 6A02 push 00000002 :0043E390 31C9 xor ecx, ecx :0043E392 8D457E lea eax, dword ptr [ebp+7E] :0043E395 E85A320000 call 004415F4 :0043E39A 68402E4E00 push 004E2E40 * Possible StringData Ref from Data Obj ->"%sdolby.mpx" <-- Dolby logo | :0043E39F 6894404B00 push 004B4094 :0043E3A4 8D457E lea eax, dword ptr [ebp+7E] :0043E3A7 50 push eax :0043E3A8 E8C30B0100 call 0044EF70 :0043E3AD 83C40C add esp, 0000000C :0043E3B0 BBE0010000 mov ebx, 000001E0 :0043E3B5 BA80020000 mov edx, 00000280 :0043E3BA 6A02 push 00000002 :0043E3BC 31C9 xor ecx, ecx :0043E3BE 8D457E lea eax, dword ptr [ebp+7E] :0043E3C1 E82E320000 call 004415F4 :0043E3C6 68402E4E00 push 004E2E40 * Possible StringData Ref from Data Obj ->"%sintro.mpx" <-- Game intro (cool to watch a couple of times) | :0043E3CB 68A0404B00 push 004B40A0 :0043E3D0 8D457E lea eax, dword ptr [ebp+7E] :0043E3D3 50 push eax :0043E3D4 E8970B0100 call 0044EF70 :0043E3D9 83C40C add esp, 0000000C :0043E3DC BBE0010000 mov ebx, 000001E0 :0043E3E1 BA80020000 mov edx, 00000280 :0043E3E6 6A02 push 00000002 :0043E3E8 31C9 xor ecx, ecx :0043E3EA 8D457E lea eax, dword ptr [ebp+7E] :0043E3ED E802320000 call 004415F4 :0043E3F2 8DA596010000 lea esp, dword ptr [ebp+00000196] :0043E3F8 5D pop ebp :0043E3F9 5A pop edx :0043E3FA 59 pop ecx :0043E3FB 5B pop ebx :0043E3FC C3 ret That's the routine that plays all the logo and intro files. It has a single call to it so it should be easy enough to disable. The section the calls the above logo display routine looks like: :0043DC87 31C0 xor eax, eax :0043DC89 A0E6844B00 mov al, byte ptr [004B84E6] :0043DC8E E81564FDFF call 004140A8 :0043DC93 E8C4060000 call 0043E35C <-- Play the three logo files/movies :0043DC98 E8DFB10200 call 00468E7C :0043DC9D B838F64B00 mov eax, 004BF638 :0043DCA2 E825FB0000 call 0044D7CC Changing the call to five NOP's results in a program that starts at the main menu screen. This will save you about 20 megs on the hard drive after you delete those files (intro.mpx, dolby.mpx, and psyglogo.mpx). The edit needed to crack this game would be: Edit sw.exe at offset 260,549 ============================= Search for: E8 02 6A FC FF Change to : B8 01 00 00 00 OPTIONAL: To kill the intro files: Edit sw.exe at offset 250,003 ============================= Search for: E8 C4 06 00 00 Change to : 90 90 90 90 90 Now Shipwreckers! has been completly FiX'ed Static Vengeance